package com.zhijian.warehouse.manage.util;

import cn.hutool.http.useragent.Browser;
import cn.hutool.http.useragent.UserAgent;
import com.zhijian.util.AssertUtil;
import com.zhijian.util.BeanUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class NetUtil {
    private static final Logger log = LoggerFactory.getLogger(NetUtil.class);
    public NetUtil() {
    }


    public static String getIPV4(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (BeanUtil.isNotEmpty(ip) && !"unknown".equalsIgnoreCase(ip)) {
            return ip.indexOf(",") > -1 ? ip.substring(0, ip.indexOf(",")) : ip;
        } else {
            if (BeanUtil.isEmpty(ip) && !"unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("X-Real-IP");
            }

            if (BeanUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("Proxy-Client-IP");
            }

            if (BeanUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("WL-Proxy-Client-IP");
            }

            if (BeanUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_CLIENT_IP");
            }

            if (BeanUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getHeader("HTTP_X_FORWARDED_FOR");
            }

            if (BeanUtil.isEmpty(ip) || "unknown".equalsIgnoreCase(ip)) {
                ip = request.getRemoteAddr();
            }

            return ip;
        }
    }

    public static InetAddress getLocalAddress() {
        try {
            Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
            if (interfaces == null) {
                return null;
            }

            while(interfaces.hasMoreElements()) {
                try {
                    NetworkInterface network = (NetworkInterface)interfaces.nextElement();
                    Enumeration<InetAddress> addresses = network.getInetAddresses();

                    while(addresses.hasMoreElements()) {
                        try {
                            InetAddress address = (InetAddress)addresses.nextElement();
                            if (isValidAddress(address)) {
                                return address;
                            }
                        } catch (Throwable var4) {
                            Throwable ex = var4;
                            log.error("Failed to retrieving ip address, {}", ex.getMessage(), ex);
                        }
                    }
                } catch (Throwable var5) {
                    Throwable ex = var5;
                    log.error("Failed to retrieving ip address, {}", ex.getMessage(), ex);
                }
            }

            InetAddress localAddress = InetAddress.getLocalHost();
            if (isValidAddress(localAddress)) {
                return localAddress;
            }
        } catch (Throwable var6) {
            Throwable ex = var6;
            log.error("Failed to retrieving ip address, {}", ex.getMessage(), ex);
        }

        return null;
    }

    public static String getLocalIp() {
        InetAddress address = getLocalAddress();
        return address != null ? address.getHostAddress() : null;
    }


    public static boolean isValidAddress(InetAddress address) {
        if (address != null && !address.isLoopbackAddress()) {
            String name = address.getHostAddress();
            return name != null && !"0.0.0.0".equals(name) && !"127.0.0.1".equals(name) && matches("\\d{1,3}(\\.\\d{1,3}){3,5}", name);
        } else {
            return false;
        }
    }

    private static boolean matches(String regex, String input) {
        AssertUtil.notNull(new Object[]{regex, input},String.format("regex and input must not be null, regex: %s, input: %s", regex, input));
        return matcher(regex, input).matches();
    }
    private static Matcher matcher(String regex, String input) {
        AssertUtil.notNull(new Object[]{regex, input},String.format("regex and input must not be null, regex: %s, input: %s", regex, input));
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(input);
        return m;
    }
}
